from django.db import transaction
from django.db.models import Q
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status, filters
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from apps.club_system.club.filters import ClubCancelFilter
from apps.club_system.club.models import ClubCancel, ClubMember, Club, ClubCancelCheck, Log
from apps.club_system.club.serializers.club_cancel import ClubCancelListSerializer, ClubCancelDetailSerializer, \
    CancelSecondCheckSerializer, CancelFirstCheckSerializer, CancelPassSerializer
from utils.common import Pagination


class ClubCancelViewSet(ModelViewSet):
    '''注销社团表视图'''
    queryset = ClubCancel.objects.select_related('club', 'account').filter(is_active=True)
    pagination_class = Pagination
    filter_backends = (filters.OrderingFilter, DjangoFilterBackend)
    ordering_fields = ('id', 'created_time',)
    filter_class = ClubCancelFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return ClubCancelListSerializer
        else:
            return ClubCancelDetailSerializer

    def list(self, request, *args, **kwargs):
        if request.user.is_admin() or request.user.is_role('club_school_manager'):
            queryset = self.get_queryset()
        elif request.user.is_chairman_manager() or request.user.is_teacher_manager():
            club_ids = ClubMember.objects.filter(account=request.user, role__in=[3, 4], is_active=True) \
                .values_list('club_id', flat=True)
            queryset = self.get_queryset().filter(club_id__in=club_ids)
        else:
            queryset = self.get_queryset().none()
        queryset = self.filter_queryset(queryset)

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.first_check_status == '通过' or instance.second_check_status == '通过':
            return Response({'message': '已通过的数据无法删除'}, status=status.HTTP_400_BAD_REQUEST)
        if request.user.id == instance.account.id:
            instance.is_active = False
        else:
            return Response({'message': '无权限删除此数据！'}, status=status.HTTP_400_BAD_REQUEST)
        instance.save()
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=3,
                           table_name='ClubCancel', comment=f'删除了社团注销',
                           detail=f'删除社团名为{instance.club.name}的注销记录')
        return Response({'message': '删除成功'}, status=status.HTTP_204_NO_CONTENT)

    def create(self, request, *args, **kwargs):
        account_id = request.user.id
        club_id = request.data.get('club_id', '')
        if not club_id:
            return Response({'message': '必须有社团的id'}, status=status.HTTP_400_BAD_REQUEST)
        if not request.user.is_admin() and not request.user.is_chairman_manager():
            return Response({'message': '您无权限注销该社团！'}, status=status.HTTP_400_BAD_REQUEST)
        myapplication = self.queryset.filter(club_id=club_id, account_id=account_id)\
            .exclude(first_check_status='通过', second_check_status__in=['待审核', '通过']).exists()
        if myapplication:
            return Response({'message': '请勿重复申请'}, status=status.HTTP_400_BAD_REQUEST)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=1,
                           table_name='ClubCancel', comment=f'新增了社团注销',
                           detail=str(request.data) if request.data else '')
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        if instance.first_check_status == '通过' and instance.second_check_status in ['通过', '待审核']:
            return Response({'message': '已审核通过不可再做修改'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.account != request.user:
            return Response({'message': '只有该社团注销的创建者才能修改！'}, status=status.HTTP_400_BAD_REQUEST)
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        try:
            self.perform_update(serializer)
        except Exception as e:
            return Response({'message': e.args}, status=status.HTTP_400_BAD_REQUEST)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=2,
                           table_name='ClubCancel', comment=f'修改注销社团记录',
                           detail=f'修改社团名为{instance.club.name}的注销记录')
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='first_check_list')
    def first_check_list(self, request, *args, **kwargs):
        """ 获取一级审核待审核数据 """
        if request.user.is_admin():
            queryset = ClubCancel.objects.select_related('club', 'account') \
                .filter(first_check_status='待审核', second_check_status='待审核', is_active=True)
        else:
            account_id = request.user.id
            values = ClubMember.objects.filter(account_id=account_id, is_active=True, role=4) \
                .values_list('club_id', flat=True)
            queryset = ClubCancel.objects.select_related('club', 'account') \
                .filter(club_id__in=list(values), first_check_status='待审核', second_check_status='待审核', is_active=True)
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CancelFirstCheckSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = CancelFirstCheckSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='second_check_list')
    def second_check_list(self, request, *args, **kwargs):
        """ 获取二级审核待审核数据，一级审核过后才可以进行二级审核"""
        queryset = ClubCancel.objects.select_related('club', 'account') \
            .filter(first_check_status='通过', second_check_status='待审核', is_active=True)
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CancelSecondCheckSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = CancelSecondCheckSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    @action(methods=['post'], detail=True, url_path='first_check')
    def first_check(self, request, pk=None):
        """ 一级审核 """
        check_status = request.data.get('check_status', '')
        check_opinion = request.data.get('check_opinion', '')
        if check_status not in ('通过', '不通过'):  # 前端传过来的check_status不是通过或者不通过返回相关信息
            return Response({'message': '缺少审核状态或者审核状态错误'}, status=status.HTTP_400_BAD_REQUEST)
        if not request.user.is_admin() and not request.user.is_teacher_manager():
            return Response({'message': '您无权限进行审核！'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = ClubCancel.objects.only('id').get(id=pk)  # 找到ClubCancel中的记录
        except ClubCancel.DoesNotExist:
            return Response({'message': '错误的参数'}, status=status.HTTP_400_BAD_REQUEST)
        # 新增一级审核记录
        ClubCancelCheck.objects.create(club_cancel=instance, account_id=request.user.id, check_status=check_status,
                                       check_opinion=check_opinion, check_level=1)
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=4,
                           table_name='ClubCancel', comment=f'审核了社团名为{instance.club.name}的社团注销记录',
                           detail=f'审核状态为{check_status}, 审核意见为{check_opinion}, 为一级审核')
        # 每次审核后将一级审核状态改为最新的审核状态
        instance.first_check_status = check_status
        instance.save()
        return Response({'message': '审核成功'}, status=status.HTTP_200_OK)

    @action(methods=['post'], detail=True, url_path='second_check')
    def second_check(self, request, pk=None):
        """ 二级审核 """
        check_status = request.data.get('check_status', '')
        check_opinion = request.data.get('check_opinion', '')
        if check_status not in ('通过', '不通过'):
            return Response({'message': '缺少审核状态或者审核状态错误'}, status=status.HTTP_400_BAD_REQUEST)
        if not request.user.is_admin() and not request.user.is_role('club_school_manager'):
            return Response({'message': '您无权限进行审核！'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = ClubCancel.objects.only('id').get(id=pk)  # 找到ClubCancel中的记录
        except ClubCancel.DoesNotExist:
            return Response({'message': '错误的参数'}, status=status.HTTP_400_BAD_REQUEST)
        # 添加二级审核记录

        ClubCancelCheck.objects.create(club_cancel=instance, account_id=request.user.id, check_status=check_status,
                                       check_opinion=check_opinion, check_level=2)
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=4,
                           table_name='ClubCancel', comment=f'审核了社团名为{instance.club.name}的社团注销记录',
                           detail=f'审核状态为{check_status}, 审核意见为{check_opinion}, 为二级审核')
        if check_status == '通过':
            # 审核通过后将该社团假删除
            Club.objects.filter(id=instance.club_id).update(is_active=False)
            # 审核通过后清空全部社团成员
            ids = ClubMember.objects.filter(club_id=instance.club_id, is_active=True).values_list('id', flat=True)
            tmp = [ClubMember(id=i, is_active=False) for i in list(ids)]
            ClubMember.objects.bulk_update(tmp, fields=['is_active'])
        # 每次审核后将二级审核状态改为最新的审核状态
        instance.second_check_status = check_status
        instance.save()
        return Response({'message': '审核成功'}, status=status.HTTP_200_OK)

    @action(methods=['get'], detail=False, url_path='myapplication')
    def myapplication(self, request):
        account_id = request.user.id
        queryset = self.filter_queryset(self.get_queryset().filter(account_id=account_id))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = ClubCancelListSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = ClubCancelListSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='appliaction')
    def get_allappliaction(self, request):
        queryset = self.filter_queryset(self.get_queryset().filter(first_check_status='通过', second_check_status='通过'))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CancelPassSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = CancelPassSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)
